//import java.io.IOException;

import de.medieninf.ads.ADSTool;

public class Aufgabe1 {

          
        
        /**
         * Returns the smallest pixel in the source image
         * @param sourceImage
         * @return
         */
        public static int getSmallestPixel(int[]sourceImage) {
                
                int smallestValue = sourceImage[3];
                if(sourceImage[3] == 0)
                        return 0;
                else {
                        for(int i=3;i<sourceImage.length;i++) {
                                if(sourceImage[i]<smallestValue)
                                        smallestValue = sourceImage[i];
                        }
                }
                return smallestValue;
                
        }
        
        /**
         * Returns the largest pixel in the source image
         * @param sourceImage
         * @return
         */
        public static int getLargestPixel(int[]sourceImage) {
                
                int largestValue = sourceImage[3];
                if(sourceImage[3] == sourceImage[2])
                        return sourceImage[2];
                else {
                        for(int i=3;i<sourceImage.length;i++) {
                                if(sourceImage[i]>largestValue)
                                        largestValue = sourceImage[i];
                        }
                }
                return largestValue;
                
        }
        

/**
 * Makes the whole image brighter
 * @param percent
 * @param sourceImage
 * @return
 */
        public static int[] heller(int percent, int[] sourceImage) {

                int[] returnImage = new int[sourceImage.length];
                returnImage[0] = sourceImage[0];
                returnImage[1] = sourceImage[1];
                returnImage[2] = sourceImage[2];
                for (int i = 3; i < returnImage.length; i++) {
                        returnImage[i] = sourceImage[i] + (percent * sourceImage[2] / 100);
                        if(returnImage[i] > 255)
                                returnImage[i] = 255;
                }
                System.out.println("Edited Image: heller " + percent + " %");
                return returnImage;

        }

        public static int[] gamma(double gammaValue, int[] sourceImage) {

                int[] returnImage = new int[sourceImage.length];
                returnImage[0] = sourceImage[0];
                returnImage[1] = sourceImage[1];
                returnImage[2] = sourceImage[2];
                for (int i = 3; i < returnImage.length; i++) {
                        returnImage[i] = (int) (sourceImage[i] * Math.pow((double) sourceImage[i]/(double) sourceImage[2], gammaValue));
                }
                System.out.println("Edited Image: gamma " + gammaValue + " ");
                return returnImage;

        }

        public static int[] spreizen(int sprValue, int[] sourceImage) {

                int[] returnImage = new int[sourceImage.length];
                returnImage[0] = sourceImage[0];
                returnImage[1] = sourceImage[1];
                returnImage[2] = sourceImage[2];
                
                int top = sourceImage[2];
                int bottom = 0;
                int newBottom = getSmallestPixel(sourceImage); //a
                int newTop = getLargestPixel(sourceImage); //b
                
                for (int i = 3; i < returnImage.length; i++) {
                        
                        if(sprValue == 100) {
                                returnImage[i] = (int) (top*(((double)sourceImage[i]-bottom)/((double)top-bottom)));
                        } else if(sprValue < 100) {
                                double calBottom = (newBottom*((double)((100-sprValue))/100));
                                bottom = (int)calBottom;
                                double calTop = newTop+(top-newTop)*(double)(sprValue)/100;
                                top = (int)calTop;
                                returnImage[i] = (int) (top*(((double)sourceImage[i]-bottom)/((double)top-bottom)));
                                
                        }
                }
                System.out.println("Edited Image: spreizen " + sprValue + " %");
                return returnImage;

        }

        public static int[] binarisieren(int binValue, int[] sourceImage) {

                int[] returnImage = new int[sourceImage.length];
                returnImage[0] = sourceImage[0];
                returnImage[1] = sourceImage[1];
                returnImage[2] = sourceImage[2];
                for (int i = 3; i < returnImage.length; i++) {
                        
                        if(sourceImage[i]>binValue || sourceImage[i]==binValue) {
                                returnImage[i] = returnImage[2];
                        } else {
                                returnImage[i] = 0;
                        }
                }
                System.out.println("Edited Image: binarisieren " + binValue + " ");
                return returnImage;

        }

        public static void showImage(int[] image, int counter, int height, int width) {

                for (int i = 0; i < height; i++) {
                        for (int j = 0; j < width; j++) {

                                System.out.print(image[counter] + " ");
                                counter++;
                        }
                        System.out.println();
                }

        }

        public static void main(String[] args) {

                if (args.length < 4) {
                        System.out.println("Not enought arguments!");
                } else {

                        String function = args[0];
                        String value = args[1];
                        String sourceFile = args[2];
                        String targetFile = args[3];

                        int[] sourceImage = ADSTool.readPGM(sourceFile);
                        int[] targetImage = new int[sourceImage.length];

                        // Wert von "heller" prfen und aufrufen

                        
                        if (function.equals("heller")) {

                                int percent = Integer.valueOf(value);
                                if (percent > 100 || percent < -100) {
                                        System.out
                                                        .println("Prozent au§erhalb des gltigen Bereichs! (-100 - 100");
                                } else {
                                        targetImage = heller(percent, sourceImage);
                                        ADSTool.savePGM(targetFile, targetImage);
                                }

                                // Wert von "gamma" prfen und aufrufen

                        } else if (function.equals("gamma")) {

                                double gammaValue = Double.valueOf(value);
                                if (gammaValue < 0.0 || gammaValue > 10.0) {
                                        System.out
                                                        .println("Werte au§erhalb des gltigen Bereichs! (0.0 - 10.0");
                                } else {

                                        targetImage = gamma(gammaValue, sourceImage);
                                        ADSTool.savePGM(targetFile, targetImage);
                                }

                                // Wert von "spreizen" prfen und aufrufen

                        } else if (function.equals("spreizen")) {

                                int sprValue = Integer.valueOf(value);
                                if (sprValue < 0 || sprValue > 100) {
                                        System.out
                                                        .println("Werte au§erhalb des gltigen Bereichs! (0 - 100");
                                } else {

                                        targetImage = spreizen(sprValue, sourceImage);
                                        ADSTool.savePGM(targetFile, targetImage);
                                }

                                // Wert von "binarisieren" prfen und aufrufen

                        } else if (function.equals("binarisieren")) {

                                int binValue = Integer.valueOf(value);
                                if (binValue < 0 || binValue > 255) {
                                        System.out
                                                        .println("Werte au§erhalb des gltigen Bereichs! (0 - 255");
                                } else {

                                        targetImage = binarisieren(binValue, sourceImage);
                                        ADSTool.savePGM(targetFile, targetImage);
                                }
                                

                        }

                }

        }

}
